#pragma once

#include <stdint.h>
#include <string>
using std::string;

namespace Graph
{

/** @class Color.
  * @brief Цвет.
  *
  * Цвет в формате RGBA.
  */
class Color
{
protected:
    uint8_t m_r;    ///< красная компонента цвета.
    uint8_t m_g;    ///< зеленая компонента цвета.
    uint8_t m_b;    ///< синяя компонента цвета.
    uint8_t m_a;    ///< альфа компонента цвета.

    /**
      * Преобразует вещественное значение компоненты цвета в байтовое.
      * Ожидается вещественное значение в интервале [0, 1].
      * Значения компонент меньше нуля преобразуются в 0.
      * Значения компоненты больше 1.0 преобразуются к 255.
      *
      * @param color вещественное значение компоненты цвета.
      * @return байтовое значение компоненты цвета.
      */
    static uint8_t floatToByte(const float color);

public:
    /**
      * Конструтор по умолчанию.
      * Создает непрозрачный черный цвет.
      */
    Color();

    /**
      * Конструктор копирования.
      *
      * @param other копируемый цвет.
      */
    Color(const Color &other);

    /**
      * Конструктор из компонент цвета.
      *
      * @param r красная компонента цвета.
      * @param g зеленая компонента цвета.
      * @param b синяя компонента цвета.
      * @param a альфа компонента цвета.
      */
    Color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a = 255);

    /**
      * Конструктор из вещественных компонент цвета.
      * Значения компонент меньше нуля преобразуются в 0.0.
      * Значения компоненты больше 1.0 преобразуются к 1.0.
      *
      * @param r красная компонента цвета.
      * @param g зеленая компонента цвета.
      * @param b синяя компонента цвета.
      * @param a альфа компонента цвета.
      */
    Color(const float rf, const float gf, const float bf, const float af = 1.0f);

    /**
      * Деструктор.
      */
    virtual ~Color();

    /**
      * Get-метод для красной компоненты цвета.
      *
      * @return красная компонента цвета.
      */
    uint8_t getR() const
    {
        return m_r;
    }

    /**
      * Get-метод для зеленой компоненты цвета.
      *
      * @return зеленая компонента цвета.
      */
    uint8_t getG() const
    {
        return m_g;
    }

    /**
      * Get-метод для синей компоненты цвета.
      *
      * @return синяя компонента цвета.
      */
    uint8_t getB() const
    {
        return m_b;
    }

    /**
      * Get-метод для альфа компоненты цвета.
      *
      * @return альфа компонента цвета.
      */
    uint8_t getA() const
    {
        return m_a;
    }

    /**
      * Set-метод для красной компоненты цвета.
      *
      * @param r красная компонента цвета.
      */
    void setR(const uint8_t r)
    {
        m_r = r;
    }

    /**
      * Set-метод для зеленой компоненты цвета.
      *
      * @param g зеленая компонента цвета.
      */
    void setG(const uint8_t g)
    {
        m_g = g;
    }

    /**
      * Set-метод для синей компоненты цвета.
      *
      * @param b синяя компонента цвета.
      */
    void setB(const uint8_t b)
    {
        m_b = b;
    }

    /**
      * Set-метод для альфа компоненты цвета.
      *
      * @param a альфа компонента цвета.
      */
    void setA(const uint8_t a)
    {
        m_a = a;
    }

    /**
      * Возвращает строковое представление цвета.
      *
      * @return строковое представление цвета.
      */
    string toString() const;

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return черный (#000) цвет.
      */
    static Color black()
    {
        return Color((uint8_t)0, (uint8_t)0, (uint8_t)0);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return белый (#fff) цвет.
      */
    static Color white()
    {
        return Color((uint8_t)255, (uint8_t)255, (uint8_t)255);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return красный (#f00) цвет.
      */
    static Color red()
    {
        return Color((uint8_t)255, (uint8_t)0, (uint8_t)0);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return зеленый (#008000) цвет.
      */
    static Color green()
    {
        return Color((uint8_t)0, (uint8_t)128, (uint8_t)0);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return синий (#00f) цвет.
      */
    static Color blue()
    {
        return Color((uint8_t)0, (uint8_t)0, (uint8_t)255);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return серый (#808080) цвет.
      */
    static Color gray()
    {
        return Color((uint8_t)128, (uint8_t)128, (uint8_t)128);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return серебрянный (#C0C0C0) цвет.
      */
    static Color silver()
    {
        return Color((uint8_t)192, (uint8_t)192, (uint8_t)192);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return желтый (#ff0) цвет.
      */
    static Color yellow()
    {
        return Color((uint8_t)255, (uint8_t)255, (uint8_t)0);
    }

    /**
      * Возвращает новый экземпляр цвета.
      * @see http://www.w3.org/TR/css3-color.
      *
      * @return фиолетовый (#800080) цвет.
      */
    static Color purple()
    {
        return Color((uint8_t)128, (uint8_t)0, (uint8_t)128);
    }
};

}
